AWS IoTで証明書からデバイスを特定してみる
こんにちは、CX事業本部の夏目です。
IoTシステムのバックエンドをサーバーレスで開発しています。
今回、デバイスにデバイスIDをもたせたくない、けど送られたデータの区別はしたいということで、MQTTの通信に使う証明書からデバイスの特定をしてみました。
やってみる
デバイス -> IoT Rule -> Lambda
という構成にしてやってみようと思います。
AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Resources: Function: Type: AWS::Serverless::Function Properties: Runtime: python3.7 Timeout: 60 MemorySize: 256 CodeUri: src Handler: index.handler Policies: - arn:aws:iam::aws:policy/AWSIoTFullAccess Events: IoTRule: Type: IoTRule Properties: AwsIotSqlVersion: 2016-03-23 Sql: SELECT principal() as principal FROM 'iot/rule'
import boto3 iot = boto3.client('iot') def handler(event, context): principal = event['principal'] arn = get_certificate_arn(principal) things = get_linked_things(arn) return things def get_certificate_arn(principal): resp = iot.describe_certificate(certificateId=principal) return resp['certificateArn'] def get_linked_things(certificate_arn): resp = iot.list_principal_things(principal=certificate_arn) return resp['things']
解説
IoT RuleのSQLでは組み込み関数としてprincipal()
があります。
端的に言うと、デバイスがMQTTで接続する際に使用している証明書のIDを返す関数です。
(何を使ってPublishしたかによって値が変わります。具体的な内容はドキュメントを見てください)
証明書のIDをIoT RuleのSQLで取得できたのであとは、AWS SDKを使ってデバイスの特定を行います。
IoTのlist_principal_things
という関数で証明書に紐づくデバイスの一覧を取得できます。
注意する点としては、引数としてprincipal
を要求されますが必要な値は証明書のARN
という点です。
(ここでは、証明書の詳細を取得してARNを取得しましたが、リージョンやAWSのアカウントIDがわかれば、自分で生成することもできます)
まとめ
証明書から紐づくデバイスを参照することができました。
証明書が1つのデバイスに紐づく場合にしか使用できませんが、こんなこともできるんだと心の片隅にでも覚えてもらえれば幸いです。